import { useCallback, useEffect, useRef } from 'react';
import MapFactory, { getGeojsonPointDataSource, removePopupById, openMarkerCom } from 'src/utils/mapFactory';
import mapMarker from '@/images/map-marker.png';
import mapActiveMarker from '@/images/map-active-marker.png';
import setting from './setting';

const scatterPopupId = 'esScatter';
function EScatter({ data, justMap, id, config, defaultZoom, bigScreen, events, editable }) {
  if (!justMap) return null;
  const { highlightMarker = '', scatterDefault, cluster, tooltip } = config;
  const { iconSize, unClusterIconTextSize, unClusterIconTextColor, defalutIcon, highlighIcon } = scatterDefault;
  const { useCluster } = cluster;
  const {
    type: clusterStatus,
    clusterCircleRadius,
    clusterTextColor,
    clusterCircleColor,
    clusterTextSize,
    clusterCircleStrokeColor,
    clusterCircleStrokeWidth,
    clusterCircleStrokeOpacity,
    clusterRadius,
  } = useCluster;
  const { tooltipShow } = tooltip;
  const scatterLayerId = `scatter_${id}`;
  const mapFactory = MapFactory(justMap);

  // 定义geoJson数据对象，用于存储散点数据
  const geoJsonData = useRef();
  // 初始完成
  const initDone = useRef(false);
  // 创建弹窗
  const createPopup = (event) => {
    mapFactory.appPopup(event, {
      id: scatterPopupId,
      doneCallback: (el) => {
        event.tooltip = tooltip;
        openMarkerCom(event, el);
      },
    });
  };

  // 更新store中的dataPoll
  const comSetDataPool = (dataPoll) => {
    const { setDataPool } = bigScreen;
    const { click } = events;
    setDataPool(click, dataPoll);
  };

  // 鼠标进入点位时默认动作
  const mouseenterFn = useCallback((e) => {
    const featureItem = e.features[0];
    if (tooltipShow === 'hover' && featureItem) {
      e.featureItem = featureItem;
      createPopup(e, featureItem);
    }
    justMap.getCanvas().style.cursor = 'pointer';
  }, []);

  // 鼠标进入点位时默认动作
  const mouseleaveFn = useCallback(() => {
    tooltipShow === 'hover' && removePopupById(scatterPopupId);
    justMap.getCanvas().style.cursor = '';
  }, []);

  // 根据Id飞入对应点位
  const flyById = (flyId) => {
    const positionData = geoJsonData.current.features.filter((f) => f.properties.id === flyId);
    if (positionData) {
      mapFactory.flyToFeature({
        type: 'FeatureCollection',
        features: positionData,
      });
    }
  };

  // 单击时间需处理的默认动作
  const clickFn = useCallback((e) => {
    const { lngLat } = e;
    const featureItem = e.features[0];
    if (featureItem) {
      const { properties } = featureItem;
      // 设置变量
      comSetDataPool({ id: properties.id, lng: lngLat.lng, lat: lngLat.lat });
      e.featureItem = featureItem;
      tooltipShow === 'click' && createPopup(e);
      mapFactory.pointWeight(scatterLayerId, featureItem.properties.id, iconSize);
    }
  }, []);
  /**
   * 生成聚合图层对象
   * @param {*} geoJeson
   * @param {*} activeId
   * @returns
   */
  const createGroupLayerObj = (geoJeson) => ({
    id: scatterLayerId,
    type: 'just_cluster',
    source: {
      type: 'geojson',
      data: geoJeson,
      cluster: clusterStatus,
      clusterMaxZoom: 14,
      clusterRadius,
    },
    paint: {
      clusterCircleColor,
      clusterCircleRadius,
      clusterCircleStrokeWidth,
      clusterCircleStrokeColor,
      clusterCircleStrokeOpacity,
      clusterTextColor,
      unClusterIconTextColor,
    },
    layout: {
      clusterTextSize,
      unClusterIconSize: iconSize,
      clusterTextAllowOverlap: true,
      unClusterTextAllowOverlap: true,
      clusterIconAllowOverlap: true,
      unClusterIconAllowOverlap: true,
      unClusterIconIgnorePlacement: true,
      unClusterIconImage: ['case', ['==', ['get', 'id'], highlightMarker], `mapActiveMarker_${id}`, `mapMarker_${id}`],
      unClusterIconText: tooltipShow === 'hide' ? 'text' : '',
      unClusterIconTextSize,
      unClusterIconTextJustify: 'left',
      unClusterIconTextAnchor: 'top',
    },
  });

  // 清空图层
  const clearLayer = (delImg) => {
    if (justMap) {
      // 清除浮层
      removePopupById(scatterPopupId);
      if (justMap.getLayer(scatterLayerId)) {
        justMap.removeLayer(scatterLayerId);
        justMap.removeSource(scatterLayerId);
      }
      delImg && justMap.removeImage(`mapMarker_${id}`);
      delImg && justMap.removeImage(`mapActiveMarker_${id}`);
    }
  };

  useEffect(() => {
    mapFactory.addStaticImg(id, {
      defalutIcon,
      highlighIcon,
    });
  }, []);

  // 填写变量名名时，初始化变量
  useEffect(() => {
    comSetDataPool({ id: '', lng: '', lat: '' });
  }, [JSON.stringify(events)]);

  // 重新渲染散点
  useEffect(() => {
    if (justMap) {
      if (data && data.length !== 0) {
        clearLayer();
        // 初始化变量
        comSetDataPool({ id: '', lng: '', lat: '' });
        geoJsonData.current = getGeojsonPointDataSource(data);

        // 添加聚合图层
        const groupLayer = createGroupLayerObj(geoJsonData.current);
        justMap.addLayer(groupLayer);
        // 聚合状态缩放到默认层级，非聚合状态根据散点数据计算缩放层级
        if (clusterStatus) {
          justMap.setZoom(defaultZoom);
        } else if (initDone.current && !editable) {
          mapFactory.flyToFeature(geoJsonData.current);
        }
        // 组装非聚合图层Id
        const unClusterIconLayerId = `${scatterLayerId}-unClusterIcon`;
        // 鼠标进入点位时默认动作
        justMap.off('mouseenter', unClusterIconLayerId, mouseenterFn);
        justMap.on('mouseenter', unClusterIconLayerId, mouseenterFn);
        // 鼠标离开点位时默认动作
        justMap.off('mouseleave', unClusterIconLayerId, mouseleaveFn);
        justMap.on('mouseleave', unClusterIconLayerId, mouseleaveFn);
        // 单击时间需处理的默认动作
        justMap.off('click', unClusterIconLayerId, clickFn);
        justMap.on('click', unClusterIconLayerId, clickFn);

        // 置顶高亮散点图层
        const istopGeo = justMap.map
          .getStyle()
          .layers.filter((f) => /scatter_(\d)*-unClusterIcon/.test(f.id))
          .find((f) => f.layout['icon-image'][1][2]);
        if (istopGeo && istopGeo.id) {
          mapFactory.layerIstop(istopGeo.id);
        }
        // 点击地图
        justMap.on('click', () => {
          tooltipShow === 'click' && removePopupById(scatterPopupId);
        });
      } else {
        clearLayer();
      }
      // 组件初始完成
      initDone.current = true;
    }
    return () => {
      clearLayer(true);
    };
  }, [JSON.stringify(data), clusterStatus, clusterRadius, tooltipShow, justMap]);

  // 更新图标样式
  useEffect(() => {
    if (justMap.getLayer(scatterLayerId) && highlightMarker) {
      // 清除浮层
      removePopupById(scatterPopupId);
      // 高亮图标
      justMap.setLayerProperty(scatterLayerId, {
        layout: {
          unClusterIconImage: ['case', ['==', ['get', 'id'], highlightMarker], `mapActiveMarker_${id}`, `mapMarker_${id}`],
        },
      });
      // 置顶高亮散点图层
      mapFactory.layerIstop(`${scatterLayerId}-unClusterIcon`);
      // 根据散点高亮Id进行飞入
      flyById(highlightMarker);
    }
  }, [highlightMarker]);

  // 更新聚合图层
  useEffect(() => {
    if (justMap.getLayer(scatterLayerId)) {
      justMap.setLayerProperty(scatterLayerId, {
        layout: {
          unClusterIconSize: iconSize,
          clusterTextSize,
          unClusterIconTextSize,
        },
      });
    }
  }, [iconSize, clusterTextSize, unClusterIconTextSize]);

  // 更新样式
  useEffect(() => {
    if (justMap.getLayer(scatterLayerId)) {
      justMap.setLayerProperty(scatterLayerId, {
        paint: {
          unClusterIconTextColor,
          clusterCircleRadius,
          clusterCircleColor,
          clusterTextColor,
          clusterCircleStrokeColor,
          clusterCircleStrokeWidth,
          clusterCircleStrokeOpacity,
        },
      });
    }
  }, [
    clusterCircleRadius,
    clusterTextColor,
    clusterCircleColor,
    unClusterIconTextColor,
    clusterCircleStrokeColor,
    clusterCircleStrokeWidth,
    clusterCircleStrokeOpacity,
  ]);

  // 更新图标
  useEffect(() => {
    if (justMap.getLayer(scatterLayerId)) {
      if (defalutIcon) {
        mapFactory.updateStaticImg(`mapMarker_${id}`, defalutIcon);
      } else {
        mapFactory.updateStaticImg(`mapMarker_${id}`, mapMarker);
      }

      if (highlighIcon) {
        mapFactory.updateStaticImg(`mapActiveMarker_${id}`, highlighIcon);
      } else {
        mapFactory.updateStaticImg(`mapActiveMarker_${id}`, mapActiveMarker);
      }
    }
  }, [defalutIcon, highlighIcon]);
  return null;
}

EScatter.setting = setting;
export default EScatter;
